package com.huika.huikalib.encrypt;

import com.huika.huikalib.utils.StringUtils;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;


public class RSAUtils {
//	private static Logger logger = Logger.getLogger(RSAUtils.class); 
    /** */
    /**
     * 加密算法RSA
     */
    public static final String KEY_ALGORITHM = "RSA";
    /** */
    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    /** */
    /**
     * 获取公钥的key
     */
    public static final String PUBLIC_KEY = "RSAPublicKey";
    /** */
    /**
     * 获取私钥的key
     */
    public static final String PRIVATE_KEY = "RSAPrivateKey";

    public static final String QSTRING_EQUAL = "=";
    public static final String QSTRING_SPLIT = "&";
    //SIGN
    public final static String SIGNATURE = "sign";
    public final static String RSCODE = "rsCode";
    public final static String RSMEG = "rsMsg";


    /**
     * 生成字符串类型的公钥、私钥对
     *
     * @return
     * @throws Exception
     */
    public static Map<String, String> generateKeys() throws Exception {
        Map<String, String> keysMap = new HashMap<String, String>();
        KeyPair kp = RsaHelper.generateRSAKeyPair();
        PublicKey pubKey = kp.getPublic();
        PrivateKey priKey = kp.getPrivate();
        String pubKeyXml = RsaHelper.encodePublicKeyToXml(pubKey);
        String priKeyXml = RsaHelper.encodePrivateKeyToXml(priKey);
//        String pubKeyXml = RsaHelper.encode64PublicKeyString(pubKey);
//        String priKeyXml = RsaHelper.encode64PrivateKeyString(priKey);
        keysMap.put(RSAUtils.PUBLIC_KEY, pubKeyXml);
        keysMap.put(RSAUtils.PRIVATE_KEY, priKeyXml);
        return keysMap;
    }

    /** */
    /**
     * <p>
     * 公钥加密      兼容模式
     * </p>
     *
     * @param sourceData 源数据
     * @param publicKey  公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String sourceData, String publicKey) throws Exception {

        PublicKey publicKeyObj = RsaHelper.decodePublicKeyFromXml(publicKey);
//    	PublicKey publicKeyObj = RsaHelper.decodePublicKeyFromBase64Str(publicKey);
        byte[] sourceDataByteArray = sourceData.getBytes("utf-8");
        byte[] encodeDataByteArray = RsaHelper.encryptData(sourceDataByteArray, publicKeyObj);
        return Base64Helper.encode(encodeDataByteArray);
    }

    /**
     * 私钥解密     兼容模式
     *
     * @param encryptedData 已加密数据
     * @param privateKey    私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String encryptedData, String privateKey) throws Exception {
        PrivateKey privateKeyObj = RsaHelper.decodePrivateKeyFromXml(privateKey);
//     PrivateKey privateKeyObj = RsaHelper.decodePrivateKeyFromBase64Str(privateKey);
        byte[] encryptedDataArray = Base64Helper.decode(encryptedData);
        byte[] decryptedDataByteArray = RsaHelper.decryptData(encryptedDataArray, privateKeyObj);
        if (decryptedDataByteArray == null) return null;
        String decryptedData = new String(decryptedDataByteArray, "utf-8");
        return decryptedData;

    }

    /** */
    /**
     * <p>
     * 私钥加密      兼容模式
     * </p>
     *
     * @param sourceData
     * @param privateKey 公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String encryptByPrivateKey(String sourceData, String privateKey) throws Exception {

        PrivateKey privateKeyObj = RsaHelper.decodePrivateKeyFromXml(privateKey);
        byte[] sourceDataByteArray = sourceData.getBytes("utf-8");
        byte[] encodeDataByteArray = RsaHelper.encryptData(sourceDataByteArray, privateKeyObj);
        return Base64Helper.encode(encodeDataByteArray);
    }

    /**
     * 公钥解密     兼容模式
     *
     * @param encryptedData 已加密数据
     * @param publicKey     公钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String decryptByPublicKey(String encryptedData, String publicKey) throws Exception {
        PublicKey publicKeyObj = RsaHelper.decodePublicKeyFromXml(publicKey);
        byte[] encryptedDataArray = Base64Helper.decode(encryptedData);
        byte[] decryptedDataByteArray = RsaHelper.decryptData(encryptedDataArray, publicKeyObj);
        if (decryptedDataByteArray == null) return null;
        String decryptedData = new String(decryptedDataByteArray, "utf-8");
        return decryptedData;
    }

    /**
     * 公钥加密   普通模式
     *
     * @param data      待加密字符串
     * @param publicKey 公钥
     * @return String
     * @throws Exception
     * @Description:
     * @author 陈权
     * @date 2015年3月24日 下午9:44:35
     * @version V1.0
     */
    public static String publicCommonEncrypt(String data, String publicKey) throws Exception {

        PublicKey publicKeyObj = RsaHelper.loadPublicKeyByStr(publicKey);
        byte[] sourceDataByteArray = data.getBytes("utf-8");
        byte[] encodeDataByteArray = RsaHelper.encryptData(sourceDataByteArray, publicKeyObj);
        return Base64Helper.encode(encodeDataByteArray);
    }

    /**
     * 私钥解密   普通类型
     *
     * @param encryptedData 已加密数据
     * @param privateKey    私钥(BASE64编码)
     * @return
     * @throws Exception
     */
    public static String decryptComonByPrivateKey(String encryptedData, String privateKey) throws Exception {
        PrivateKey privateKeyObj = RsaHelper.loadPrivateKeyByStr(privateKey);
        byte[] encryptedDataArray = Base64Helper.decode(encryptedData);
        byte[] decryptedDataByteArray = RsaHelper.decryptData(encryptedDataArray, privateKeyObj);
        if (decryptedDataByteArray == null) return null;
        String decryptedData = new String(decryptedDataByteArray, "utf-8");
        return decryptedData;
    }

    /**
     * 公钥加密（json字符串、实体对象使用）     兼容模式
     *
     * @param object
     * @param publicKey 子系统公钥
     * @return String
     * @throws Exception
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午7:15:37
     * @version V1.0
     */
    public static String publicRequestEncrypt(Object object, String publicKey) throws Exception {
        HashMap<String, String> data = new HashMap<String, String>();
        JSONObject jsonObject = JSONUtils.toJSONObject(object);
        if (!jsonObject.isNullObject()) {
            Iterator it = jsonObject.keys();
            while (it.hasNext()) {
                String key = String.valueOf(it.next());
                Object value = jsonObject.get(key);
                if (null != value && !value.equals("null")) {
                    data.put(key, String.valueOf(value));
                }
            }
        }
        String nvp = buildReq(data, false);
//		logger.info("【待签名字符串】"+nvp);
        return encryptByPublicKey(nvp, publicKey);
    }

    /**
     * 公钥加密   兼容模式
     *
     * @param data      待加密Map
     * @param publicKey 公钥
     * @return String
     * @throws Exception
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午9:44:35
     * @version V1.0
     */
    public static String publicRequestEncrypt(Map<String, String> data, String publicKey) throws Exception {
        String nvp = buildReq(data, false);
//		logger.info("【待签名字符串】"+nvp);
        return encryptByPublicKey(nvp, publicKey);
    }


    /**
     * 公钥加密   普通模式
     *
     * @param data      待加密Map
     * @param publicKey 公钥
     * @return String
     * @throws Exception
     * @Description:
     * @author 陈权
     * @date 2015年3月24日 下午9:44:35
     * @version V1.0
     */
    public static String publicCommonEncrypt(Map<String, String> data, String publicKey) throws Exception {
        String nvp = buildReq(data, false);
//        logger.info("【待签名字符串】"+nvp);
        return publicCommonEncrypt(nvp, publicKey);
    }


    /**
     * 公钥加密   普通模式
     *
     * @param object    待加密对象（json字符串、实体对象使用）
     * @param publicKey 公钥
     * @return String
     * @throws Exception
     * @Description:
     * @author 陈权
     * @date 2015年3月24日 下午9:44:35
     * @version V1.0
     */
    public static String publicCommonEncrypt(Object object, String publicKey) throws Exception {
        HashMap<String, String> data = new HashMap<String, String>();
        JSONObject jsonObject = JSONUtils.toJSONObject(object);
        if (!jsonObject.isNullObject()) {
            Iterator it = jsonObject.keys();
            while (it.hasNext()) {
                String key = String.valueOf(it.next());
                Object value = jsonObject.get(key);
                if (null != value && !value.equals("null")) {
                    data.put(key, String.valueOf(value));
                }
            }
        }
        String nvp = buildReq(data, false);
//        logger.info("【待签名字符串】"+nvp);
        return publicCommonEncrypt(nvp, publicKey);
    }


    /**
     * API接口返回数据 公钥加密（json字符串、实体对象使用）     兼容模式
     *
     * @param object
     * @param publicKey 子系统公钥
     * @return String
     * @throws Exception
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午7:17:24
     * @version V1.0
     */
    public static String publicReturnEncrypt(Object object, String publicKey) throws Exception {
        HashMap<String, String> data = new HashMap<String, String>();
        JSONObject jsonObject = JSONUtils.toJSONObject(object);
        if (!jsonObject.isNullObject()) {
            Iterator it = jsonObject.keys();
            while (it.hasNext()) {
                String key = String.valueOf(it.next());
                Object value = jsonObject.get(key);
                if (null != value && !value.equals("null")) {
                    data.put(key, String.valueOf(value));
                }
            }
        }
        String nvp = buildReq(data, true);
//		logger.info("【待签名字符串】"+nvp);
        return encryptByPublicKey(nvp, publicKey);
    }

    /**
     * 验密
     *
     * @param paramMap
     * @param privateKey 钱包私钥
     * @return boolean
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午7:16:03
     * @version V1.0
     */
    public static boolean privateDecrypt(Map<String, String> paramMap, String privateKey) {
        // 获取请求参数中的签名域
        String sign = paramMap.get(SIGNATURE);
//		logger.info("【请求验签|请求签名域】"+sign);
        if (StringUtils.isEmpty(sign)) {
            return false;
        }
        // 拼接请求字符串
        String nvp = buildReq(paramMap, false);
//		logger.info("【请求验签|签名参数】"+nvp);
        try {
            return nvp.equalsIgnoreCase(decryptByPrivateKey(sign, privateKey));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 组装签名参数
     *
     * @param req  签名参数
     * @param type true：仅用于创建返回签名域  false：创建请求签名域和其他
     * @return String
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午3:47:25
     * @version V1.0
     */
    public static String buildReq(Map<String, String> req, boolean type) {
        // 除去数组中的空值和签名参数
        Map<String, String> filteredReq = paraFilter(req, type);
        String prestr = createLinkString(filteredReq);
        return prestr;
    }

    /**
     * 拼接签名字符串
     *
     * @param para
     * @return String
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午2:32:11
     * @version V1.0
     */
    @SuppressWarnings("unchecked")
    public static String createLinkString(Map<String, String> para) {

        List<String> keys = new ArrayList<String>(para.keySet());
        // 根据key值作升序排列
        Collections.sort(keys, new Comparator() {
            public int compare(Object a, Object b) {
                return a.toString().toLowerCase().compareTo(b.toString().toLowerCase());
            }
        });
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = para.get(key);

            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                sb.append(key).append(QSTRING_EQUAL).append(value);
            } else {
                sb.append(key).append(QSTRING_EQUAL).append(value).append(QSTRING_SPLIT);
            }
        }
        return sb.toString();
    }

    /**
     * 过滤空值、签名域
     *
     * @param para
     * @param type true：接口返回签名（使用）  false：请求签名
     * @return Map<String,String>
     * @Description:
     * @author 刘恒
     * @date 2015年3月24日 下午2:34:19
     * @version V1.0
     */
    public static Map<String, String> paraFilter(Map<String, String> para, boolean type) {

        Map<String, String> result = new HashMap<String, String>();

        if (para == null || para.size() <= 0) {
            return result;
        }

        for (String key : para.keySet()) {
            String value = String.valueOf(para.get(key));
            if (type && !key.equalsIgnoreCase(RSCODE) && !key.equalsIgnoreCase(RSMEG)) {
                continue;
            }
            // 排除空值、签名域
            if (value == null || value.equals("") || key.equalsIgnoreCase(SIGNATURE)) {
                continue;
            }
            result.put(key, value);
        }

        return result;
    }


    public static void mai1n(String[] args) throws Exception {
        Map<String, String> keysMap = RSAUtils.generateKeys();
        System.out.println("公钥:" + keysMap.get(RSAUtils.PUBLIC_KEY));
        System.out.println("私钥:" + keysMap.get(RSAUtils.PRIVATE_KEY));
    }

    public static void main(String[] args) {
        try {
//			System.out.println(encryptByPublicKey("B327AA58A62BAB24B309DB51BA739E6A","<RSAKeyValue><Modulus>AK1QGJyHpz0HImND6AGlkujSk86AUFiF5L66bnbe4L1MssR4wR78PCTokE4/GyfA6KrFd8xg5FZi4Uv8enUCkfnlYC1P+VxqqeaVJb99/tV8icRTnAuLsA0OJqv7qVRSa8PBLkMRr25ndsAcc3tbt56f2mxziLSQxygugp5cAnFD</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"));
            String data = "nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进nginx由于出色的性能，在世界范围内受到了越来越多人的关注，在淘宝内部它更是被广泛的使用，众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理，但是国内却没有一本关于这方面的书，源于此我们决定自己来写一本。本书的作者为淘宝核心系统服务器平台组的成员，本书写作的思路是从模块开发逐渐过渡到nginx原理剖析。书籍的内容会定期在这里更新，欢迎大家提出宝贵意见，不管是本书的内容问题，还是字词错误，都欢迎大家提交issue(章节标题的左侧有评注按钮)，我们会及时的跟进";
            String publicKeyObj = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUgNk/+xecgoi+P8Xg/AnBgKbYBQRicpVAV+hSTOkgkrM1weAlE/t+bs8J0rEkkHCyaqHoQkfmcKvhoEPd/zcbWj+vGVscGexvQEihhtxmRpuA++7IqsLKfAejUekJCe8q2mF/V6mAAfrWOUS9aTIYol1C5xLf1SbdZrywC9/s/wIDAQAB";
            String privateKeyObj = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJSA2T/7F5yCiL4/xeD8CcGAptgFBGJylUBX6FJM6SCSszXB4CUT+35uzwnSsSSQcLJqoehCR+Zwq+GgQ93/NxtaP68ZWxwZ7G9ASKGG3GZGm4D77siqwsp8B6NR6QkJ7yraYX9XqYAB+tY5RL1pMhiiXULnEt/VJt1mvLAL3+z/AgMBAAECgYAHQ75c+OWQzHnwBKKjfPDlPGvtCWHLhxtyCFrfG9ATvdlyeceDSNT2vGj4bAwqY75/m+PLvuJRjZV69iIbzA5f/xSmOcOoFrTBqAN60uvOWMdVy7l18EQn0o2KW3KIV/cYZ8NFk1rqXfwnLBReMYUwGrGZOhYIuN5D+6/5X4SewQJBAMr+KC3JMJAyYDwEF28pw8UMNPJwvgeeLUT6h+XQgm7j4DqlNYncS2eJqhiB7MmA51qNC1HHs82Vpx5rmo7sifECQQC7SCFRTwRsHV0Mez/1oZr0FygFFIGi0OyHl1XLNM86yhqlMOwrWM5SsescfF19Fic6lPl8HrXwVO/buUiiAHXvAkBoB0wr+rkqjMaIu0gPLgYoC5Nu05xvZv6oJQRUIEFX9uxI4bXISt9R1lkXai4hLjBiVXoBlShuKU2V52sz58DhAkABP7DhLuqzodp9+9BoXeR/nivpJMLciBIbsVmkGj0Lgk99LH9WpqfxizgrH3UsIVqvnFCxkC7cZGSZDXo7gk9HAkEAqub7agAB6Y+0UlklNyVN3kFs80waInfxwYzcVxD7tgckAnZeMGV7dWzDRPoHypSh8uZ98/LKpwJ02ihasJwhMA==";
          /*  byte [] sourceDataByteArray = data.getBytes("utf-8");
	        byte [] encodeDataByteArray = RsaHelper.encryptData(sourceDataByteArray, loadPublicKeyByStr(publicKeyObj));
	        String encryptedData = Base64Helper.encode(encodeDataByteArray);
	        
	        
	        byte [] encryptedDataArray = Base64Helper.decode(encryptedData);
	        byte [] decryptedDataByteArray = RsaHelper.decryptData(encryptedDataArray, loadPrivateKeyByStr(privateKeyObj));
	        String decryptedData = new String(decryptedDataByteArray, "utf-8");
	        System.out.println("原文："+data);
	        System.out.println("加密密文："+encryptedData);
		    System.out.println("解密密文："+decryptedData);*/


            String encryptedData2 = publicCommonEncrypt(data, publicKeyObj);
            String decryptedData2 = decryptComonByPrivateKey(encryptedData2, privateKeyObj);
            System.out.println("加密密文2：" + encryptedData2);
            System.out.println("解密密文2：" + decryptedData2);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
